package kube_service

import (
	"errors"
	"go.uber.org/zap"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"virtual-resource-schedule-service/client/kube_client"
	"virtual-resource-schedule-service/global"
	"virtual-resource-schedule-service/model/kube_pod"
	"virtual-resource-schedule-service/repository"
	"virtual-resource-schedule-service/utils"
)

type IPodApiService interface {
	CreateContainer(podRequest kube_pod.PodRequest) (response *kube_pod.PodResponse, err error)
	StartContainer(req kube_pod.StartPodReq) (*kube_pod.StartPodResp, error)
	ShutdownContainer(req kube_pod.ShutdownPodReq) (*kube_pod.ShutdownPodResp, error)
}

type PodApiService struct {
	// @TODO 需要调整为 [clusterId, client] map结构，需要调整为全局变量，避免每次都需要创建连接
	PodK8SClient *kube_client.PodK8SClient
}

var clusterRepository = repository.NewClusterRepository()

func NewPodApiService(clusterId string) *PodApiService {
	// @TODO 根据clusterId获取对应kubeconfig
	// 如果map中cluster已经加载了Client则不用再操作
	K8sClient := global.PodK8sClientMap[clusterId]
	if K8sClient == nil {
		record, dbErr := clusterRepository.QueryByClusterById(clusterId)
		// @TODO 从数据库中查询得到
		if dbErr != nil {
			return nil
		}
		kubeconfig := record.KubeconfigLocalPath
		zap.S().Infof("kubeconfig : %s", kubeconfig)
		// k8s的client信息
		config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
		if err != nil {
			zap.S().Error("Error building kubeconfig", zap.Error(err))
		}
		clientset, err := kubernetes.NewForConfig(config)
		if err != nil {
			zap.S().Error("Error NewForConfig", zap.Error(err))
		}
		global.PodK8sClientMap[clusterId] = kube_client.NewPodK8SClient(clientset)
		service := &PodApiService{
			PodK8SClient: global.PodK8sClientMap[clusterId],
		}
		return service
	}
	// 如果在本地的map中存在则说明这个集群的client已经创建过
	service := &PodApiService{
		PodK8SClient: K8sClient,
	}
	return service
}

// CreateContainer 负责创建容器
func (podApiService *PodApiService) CreateContainer(
	podRequest kube_pod.PodRequest) (response *kube_pod.PodResponse, err error) {
	podModel := &kube_pod.Pod{}
	err = utils.SwapTo(podRequest, podModel)
	if err != nil {
		zap.S().Error(err)
		return nil, errors.New("容器创建请求-参数解析异常")
	}
	// 调用K8S的Client创建POD
	podInfo, err := podApiService.PodK8SClient.CreatePodToK8SCluster(podModel)
	if err != nil {
		zap.S().Error("CreatePodToK8SCluster", zap.Error(err))
		return nil, errors.New("容器创建到集群失败")
	}
	podResponse := kube_pod.PodResponse{
		PodName:      podInfo.PodName,
		Created:      true,
		PodNamespace: podInfo.PodNamespace,
		PodClusterId: podInfo.PodClusterId,
	}
	return &podResponse, nil
}

// StartContainer 开启容器
func (podApiService *PodApiService) StartContainer(req kube_pod.StartPodReq) (
	rsp *kube_pod.StartPodResp, err error) {
	rsp, err = podApiService.PodK8SClient.StartPodFromK8SCluster(&req)
	if err != nil {
		zap.S().Error("StartPodFromK8SCluster Failed", zap.Error(err))
		return rsp, err
	}
	return rsp, nil
}

// ShutdownContainer 开启容器
func (podApiService *PodApiService) ShutdownContainer(req kube_pod.ShutdownPodReq) (
	rsp *kube_pod.ShutdownPodResp, err error) {
	rsp, err = podApiService.PodK8SClient.ShutdownPodFromK8SCluster(&req)
	if err != nil {
		zap.S().Error("ShutdownPodFromK8SCluster Failed", zap.Error(err))
		return rsp, err
	}
	return rsp, nil
}
